import java.util.*;

/*
二分图的最大匹配
给定一个二分图，其中左半部包含 n1 个点（编号1∼n1），右半部包含 n2 个点（编号 1∼n2），二分图共包含 m 条边。
数据保证任意一条边的两个端点都不可能在同一部分中。
请你求出二分图的最大匹配数。
二分图的匹配：给定一个二分图 G，在 G 的一个子图 M 中，M 的边集 {E} 中的任意两条边都不依附于同一个顶点，则称 M 是一个匹配。
二分图的最大匹配：所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配，其边数即为最大匹配数。

输入格式
第一行包含三个整数 n1、 n2和 m。
接下来 m 行，每行包含两个整数 u 和 v，表示左半部点集中的点 u 和右半部点集中的点 v 之间存在一条边。

输出格式
输出一个整数，表示二分图的最大匹配数。

数据范围
1≤n1,n2≤500,1≤u≤n1,1≤v≤n2,1≤m≤1e5

输入样例：
2 2 4
1 1
1 2
2 1
2 2

输出样例：
2
 */
public class Main {
    static int n1, n2, m, maxMatch;
    static ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
    static int[] match = new int[501];
    static boolean[] visited = new boolean[501];

    static boolean find(int u) {
        for (int v : graph.get(u)) {
            if (!visited[v])//如果v没有被“男生”考虑过
            {
                visited[v] = true;
                if (match[v] == 0 || find(match[v])) {
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;//实在匹配不上，返回false
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n1 = sc.nextInt();
        n2 = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i <= n1; i++) {
            graph.add(new ArrayList<>());
        }
        for (int i = 1; i <= m; i++) {
            int u = sc.nextInt(), v = sc.nextInt();
            graph.get(u).add(v);
        }
        for (int i = 1; i <= n1; i++) {
            Arrays.fill(visited, false);//先把所有"妹子"清空，表示这些"妹子"在当前"男生"这里还未被考虑过
            if (find(i)) {
                maxMatch++;
            }
        }
        System.out.println(maxMatch);
    }
}